package ui

import (
	"catlib/lib/ui/collision"
	"sort"
)

// eventRegion 事件范围
// 节点需要包含一个判定范围,与范围触发后的通知事件
type eventRegion struct {
	X, Y, Z, W, H int       // 矩阵
	Call          EventCall // 回调函数
}

// eventNode  事件列表
type eventNode struct {
	APIBaseStruct
	Region []eventRegion
}

// Add 添加一个事件
func (eve *eventNode) Add(X, Y, Z, W, H int, call EventCall) EventID {
	eve.Region = append(eve.Region, eventRegion{X: X, Y: Y, Z: Z, W: W, H: H, Call: call})
	return EventID(len(eve.Region) - 1)
}

// Delete 删除一个事件
func (eve *eventNode) Delete(ID EventID) {
	defer eve.recover() // 错误拦截
	eve.Region = append((eve.Region)[:int(ID)], (eve.Region)[int(ID)+1:]...)
}

// Call 调用一个事件
func (eve *eventNode) Call(ID EventID, Type EventType, Data interface{}) {
	defer eve.recover() // 错误拦截
	if int(ID) > -1 && int(ID) < len(eve.Region) {
		(eve.Region)[int(ID)].Call(ID, Type, Data)
	}
}

// Collision 测试碰撞
func (eve *eventNode) Collision(X, Y int, Type EventType, Data interface{}) {
	defer eve.recover()               // 错误拦截
	intslist := make([]int, 0)        // 排序对象
	eveList := make(map[int][]int, 0) // 这里保存 ObjectList 列表内需要更新的对象
	// 检测碰撞
	for i, region := range eve.Region {
		if collision.RectangleToSpot(
			float64(region.X), float64(region.Y), float64(region.W), float64(region.H),
			float64(X), float64(Y),
		) {
			if _, ok := eveList[region.Z]; !ok {
				intslist = append(intslist, region.Z)
				eveList[region.Z] = make([]int, 0)
			}
			eveList[region.Z] = append(eveList[region.Z], i)
		}
	}
	if len(intslist) == 0 {
		return
	}
	// 排序
	sort.Ints(intslist)
	// 调用
	node := eveList[intslist[len(intslist)-1]]
	id := node[len(node)-1]
	(eve.Region)[id].Call(EventID(id), Type, Data)
}

// NewEvent 创建事件
func NewEvent() Event {
	return new(eventNode)
}
